/**
 * Alibaba.com.cn Inc.
 * Copyright (c) 2004-2021 All Rights Reserved.
 */
package com.hiv.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateRange;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.hiv.common.enums.ErrorCode;
import com.hiv.common.exception.BusinessException;
import com.hiv.common.param.StatisticsParam;
import com.hiv.common.response.DataPreviewStatistics;
import com.hiv.common.response.DiseaseStatistics;
import com.hiv.common.response.DoctorStatisticsInfo;
import com.hiv.common.response.DrugResistanceStatistics;
import com.hiv.common.response.InspectionTrendStatistics;
import com.hiv.common.response.RealTimeSituationStatistics;
import com.hiv.common.response.SamplerStatisticsInfo;
import com.hiv.common.utils.AssertUtil;
import com.hiv.mapper.*;
import com.hiv.mapper.domain.Admin;
import com.hiv.mapper.domain.Hospital;
import com.hiv.mapper.domain.Patient;
import com.hiv.mapper.domain.SamplingRecord;
import com.hiv.mapper.domain.SamplingRecordResult;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author zhanghong
 * @version StatisticsService.java, v 0.1 2022/9/22 23:15 下午 StatisticsService Exp $$
 */
@Service
public class StatisticsService {
    @Autowired
    private SamplingRecordMapper samplingRecordMapper;
    @Autowired
    private HospitalMapper hospitalMapper;
    @Autowired
    private PatientMapper patientMapper;
    @Autowired
    private SamplingBoxMapper samplingBoxMapper;
    @Autowired
    private AdminMapper adminMapper;

    /**
     * 采样员统计信息
     *
     * @param param
     * @return
     */
    public SamplerStatisticsInfo samplerStatistics(Admin samplingUser, StatisticsParam param) {
        Integer todaySamplingNum = samplingRecordMapper.todaySamplingNumCount(samplingUser.getId());
        Integer samplingExceptionNum = samplingRecordMapper.samplingExceptionCount(samplingUser.getId());
        Integer samplingExceptionUnResamplingNum = samplingRecordMapper.samplingUnResamplingExceptionCount(samplingUser.getId());
        Integer waitForInspectionNum = samplingRecordMapper.waitForInspectionNumCount(samplingUser.getId());
        return SamplerStatisticsInfo.builder()
                .todaySamplingNum(todaySamplingNum)
                .samplingExceptionNum(samplingExceptionNum)
                .samplingExceptionUnResamplingNum(samplingExceptionUnResamplingNum)
                .waitForInspectionNum(waitForInspectionNum).build();
    }

    /**
     * 医生统计信息
     *
     * @param param
     * @return
     */
    public DoctorStatisticsInfo dockerStatistics(Admin dockerUser, StatisticsParam param) {
        Integer waitForInspectionNum = samplingRecordMapper.waitForInspectionNumCountForDoctor(dockerUser.getHospitalId());
        Integer inspectionInNum = samplingRecordMapper.inspectionInNumCountForDocker(dockerUser.getHospitalId());
        Integer finishNum = samplingRecordMapper.finishNumCountForDocker(dockerUser.getHospitalId());
        return DoctorStatisticsInfo.builder()
                .waitForInspectionNum(waitForInspectionNum)
                .inspectionInNum(inspectionInNum)
                .finishNum(finishNum).build();
    }

    /**
     * 数据概览统计信息
     *
     * @param admin
     * @param param
     * @return
     */
    public DataPreviewStatistics dataPreviewStatistics(Admin admin, StatisticsParam param) {
        DateTime startTime = DateUtil.beginOfMonth(new Date());
        DateTime endTime = DateUtil.endOfMonth(new Date());
        Integer hospitalNum = 0;
        Integer inspectionOfficeNum = 0;
        Integer patientNum = 0;
        Integer inspectionNum = 0;
        if (admin.getType() == 0) {//超级管理员
            hospitalNum = hospitalMapper.hospitalCountByType(2);
            inspectionOfficeNum = hospitalMapper.hospitalCountByType(3);
            patientNum = patientMapper.patientCountNum();
            inspectionNum = samplingRecordMapper.inspectionFinishNumForAdmin(startTime, endTime);
        }
        if (admin.getType() == 1) {//质控中心
            hospitalNum = hospitalMapper.listByParentId(admin.getHospitalId()).size();
            inspectionOfficeNum = qualityControlCenterRelationInspection(admin.getHospitalId()).size();
            patientNum = qualityControlCenterRelationPatient(admin.getHospitalId()).size();
            inspectionNum = qualityControlCenterRelationFinishInspection(admin.getHospitalId(), startTime, endTime).size();
        }
        if (admin.getType() == 2) {//医院
            hospitalNum = 1;
            inspectionOfficeNum = hospitalRelationInspection(admin.getHospitalId()).size();
            patientNum = hospitalRelationPatient(admin.getHospitalId()).size();
            inspectionNum = hospitalRelationFinishInspection(admin.getHospitalId(), startTime, endTime).size();
        }
        if (admin.getType() == 3) {//检验所
            hospitalNum = inspectionRelationHospital(admin.getHospitalId()).size();
            inspectionOfficeNum = 1;
            patientNum = inspectionRelationPatient(admin.getHospitalId()).size();
            inspectionNum = inspectionRelationFinishInspection(admin.getHospitalId(), startTime, endTime).size();
        }

        DataPreviewStatistics statistics = new DataPreviewStatistics();
        statistics.setHospitalNum(hospitalNum);
        statistics.setInspectionOfficeNum(inspectionOfficeNum);
        statistics.setPatientNum(patientNum);
        statistics.setInspectionNum(inspectionNum);
        return statistics;
    }

    /**
     * 实时概况统计信息
     *
     * @param admin
     * @param param
     * @return
     */
    public RealTimeSituationStatistics realTimeSituationStatistics(Admin admin, StatisticsParam param) {
        Date yesterdayStart = DateUtil.beginOfDay(DateUtil.yesterday()).toJdkDate();
        Date yesterdayEnd = DateUtil.endOfDay(DateUtil.yesterday()).toJdkDate();
        Date todayStart = DateUtil.beginOfDay(DateUtil.date()).toJdkDate();
        Date todayEnd = DateUtil.endOfDay(DateUtil.date()).toJdkDate();

        Integer todaySamplingNum = 0;
        Integer yesterdaySamplingNum = 0;
        Integer todayInspectionNum = 0;
        Integer yesterdayInspectionNum = 0;
        //根据抗病毒编号去重后统计
        Integer todayIncreasePatientNum = 0;
        Integer yesterdayIncreasePatientNum = 0;
        //检测人数(检测中+检测完成+抗病毒编号去重)
        Integer todayInspectionPersonNum = 0;
        Integer yesterdayInspectionPersonNum = 0;
        if (admin.getType() == 0) {//超级管理员
            todaySamplingNum = samplingRecordMapper.samplingCountByRange(todayStart, todayEnd);
            yesterdaySamplingNum = samplingRecordMapper.samplingCountByRange(yesterdayStart, yesterdayEnd);

            todayInspectionNum = samplingRecordMapper.samplingFinishCountByRange(todayStart, todayEnd);
            yesterdayInspectionNum = samplingRecordMapper.samplingFinishCountByRange(yesterdayStart, yesterdayEnd);

            todayIncreasePatientNum = patientMapper.increasePatientCountByRange(todayStart, todayEnd);
            yesterdayIncreasePatientNum = patientMapper.increasePatientCountByRange(yesterdayStart, yesterdayEnd);

            todayInspectionPersonNum = samplingRecordMapper.inspectionCountByRange(todayStart, todayEnd);
            yesterdayInspectionPersonNum = samplingRecordMapper.inspectionCountByRange(yesterdayStart, yesterdayEnd);
        }
        if (admin.getType() == 1) {//质控中心
            todaySamplingNum = samplingCountForQualityControlCenterByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdaySamplingNum = samplingCountForQualityControlCenterByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);

            todayInspectionNum = samplingFinishCountForQualityControlCenterByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdayInspectionNum = samplingFinishCountForQualityControlCenterByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);

            todayIncreasePatientNum = increasePatientCountForQualityControlCenterByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdayIncreasePatientNum = increasePatientCountForQualityControlCenterByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);

            todayInspectionPersonNum = inspectionCountForQualityControlCenterByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdayInspectionPersonNum = inspectionCountForQualityControlCenterByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);
        }
        if (admin.getType() == 2) {//医院
            todaySamplingNum = samplingCountForHospitalByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdaySamplingNum = samplingCountForHospitalByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);

            todayInspectionNum = samplingFinishCountForHospitalByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdayInspectionNum = samplingFinishCountForHospitalByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);

            todayIncreasePatientNum = increasePatientCountForHospitalByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdayIncreasePatientNum = increasePatientCountForHospitalByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);

            todayInspectionPersonNum = inspectionCountForHospitalByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdayInspectionPersonNum = inspectionCountForHospitalByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);
        }
        if (admin.getType() == 3) {//检验所
            todaySamplingNum = samplingCountForInspectionByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdaySamplingNum = samplingCountForInspectionByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);

            todayInspectionNum = samplingFinishCountForInspectionByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdayInspectionNum = samplingFinishCountForInspectionByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);

            todayIncreasePatientNum = increasePatientCountForInspectionByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdayIncreasePatientNum = increasePatientCountForInspectionByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);

            todayInspectionPersonNum = inspectionCountForInspectionByRange(admin.getHospitalId(), todayStart, todayEnd);
            yesterdayInspectionPersonNum = inspectionCountForInspectionByRange(admin.getHospitalId(), yesterdayStart, yesterdayEnd);
        }

        RealTimeSituationStatistics statistics = new RealTimeSituationStatistics();
        statistics.setTodaySamplingNum(todaySamplingNum);
        statistics.setYesterdaySamplingNum(yesterdaySamplingNum);
        statistics.setTodayInspectionNum(todayInspectionNum);
        statistics.setYesterdayInspectionNum(yesterdayInspectionNum);
        statistics.setTodayIncreasePatientNum(todayIncreasePatientNum);
        statistics.setYesterdayIncreasePatientNum(yesterdayIncreasePatientNum);
        statistics.setTodayInspectionPersonNum(todayInspectionPersonNum);
        statistics.setYesterdayInspectionPersonNum(yesterdayInspectionPersonNum);
        return statistics;
    }

    /**
     * 与质控中心有关的医院集合
     * @return
     */
    private List<Long> zhiKongCenterRelationHospital(Long parentId) {
        Hospital hospital = new Hospital();
        hospital.setParentId(parentId);
        return hospitalMapper.selectList(hospital).stream().map(Hospital::getId).collect(Collectors.toList());
    }

    /**
     * 检测趋势图统计信息
     *
     * @param admin
     * @param param
     * @return
     */
    public List<InspectionTrendStatistics> inspectionTrendStatistics(Admin admin, StatisticsParam param) {
        AssertUtil.assertNotNull(param.getMonth(), "月份不能为空");
        if (admin.getType() == 3) {// 检验所
            param.setInspectionId(admin.getHospitalId());
        }
        if (admin.getType() == 2) {//医院
            param.setHospitalIdList(Lists.newArrayList(admin.getHospitalId()));
        }
        if (admin.getType() == 1) {//质控中心
            if (param.getHospitalId() != null) {
                param.setHospitalIdList(Lists.newArrayList(param.getHospitalId()));
            } else {
                // 查询质控中心下的所有医院
                param.setHospitalIdList(zhiKongCenterRelationHospital(admin.getHospitalId()));
            }
        }
        if (admin.getType() == 0) {
            //超级管理员只能选检验所
            if (param.getInspectionId() == null) {
                param.setHospitalIdList(adminMapper.listAllHospitalId());
            }
        }
        List<InspectionTrendStatistics> result = Lists.newArrayList();
        try {
            DateTime montDate = DateUtil.parse(param.getMonth(), "yyyy/MM");
            DateRange range = DateUtil.range(DateUtil.beginOfMonth(montDate), DateUtil.endOfMonth(montDate), DateField.DAY_OF_YEAR);
            // 利用多线程并发查询
            for (DateTime dateTime : range) {
                DateTime beginOfDay = DateUtil.beginOfDay(dateTime);
                DateTime endOfDay = DateUtil.endOfDay(dateTime);
                long diseaseCount = 0L;
                long drugCount = 0L;
                long diseaseDrugCount = 0L;
                // 检测数据
                List<SamplingRecord> list = samplingRecordMapper.listByCondition(param.getInspectionId(), param.getHospitalIdList(), beginOfDay.toJdkDate(), endOfDay.toJdkDate());
                if (CollectionUtils.isNotEmpty(list)) {
                    // 病载检测
                    diseaseCount = list.stream().filter(item -> Objects.equals(item.getCheckType(), 1)).count();
                    // 耐药检测
                    drugCount = list.stream().filter(item -> Objects.equals(item.getCheckType(), 2)).count();
                    // 病载&耐药检测
                    diseaseDrugCount = list.stream().filter(item -> Objects.equals(item.getCheckType(), 3)).count();
                }

                InspectionTrendStatistics disease = new InspectionTrendStatistics();
                disease.setDay(DateUtil.format(beginOfDay, "MM-dd"));
                disease.setName("病载检测");
                disease.setNum(diseaseCount + diseaseDrugCount);
                result.add(disease);
                InspectionTrendStatistics drug = new InspectionTrendStatistics();
                drug.setDay(DateUtil.format(beginOfDay, "MM-dd"));
                drug.setName("耐药检测");
                drug.setNum(drugCount + diseaseDrugCount);
                result.add(drug);
                InspectionTrendStatistics inspection = new InspectionTrendStatistics();
                inspection.setDay(DateUtil.format(beginOfDay, "MM-dd"));
                inspection.setName("检测数据");
                inspection.setNum(diseaseCount + drugCount + diseaseDrugCount);
                result.add(inspection);
            }
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "月份格式错误 格式：yyyy/mm");
        }
        return result;
    }

    /**
     * 病载含量统计信息
     *
     * @param admin
     * @param param
     * @return
     */
    public List<DiseaseStatistics> diseaseStatistics(Admin admin, StatisticsParam param) {
        AssertUtil.assertNotNull(param.getMonth(), "月份不能为空");
        if (admin.getType() == 1) {//质控中心
            if (param.getHospitalId() != null) {
                param.setHospitalIdList(Lists.newArrayList(param.getHospitalId()));
            } else {
                // 查询质控中心下的所有医院
                param.setHospitalIdList(zhiKongCenterRelationHospital(admin.getHospitalId()));
            }
        }
        if (admin.getType() == 2) {//医院
            param.setHospitalIdList(Lists.newArrayList(admin.getHospitalId()));
        }
        if (admin.getType() == 3) {//检验所
            param.setInspectionId(admin.getHospitalId());
        }
        if (admin.getType() == 0) {
            //超级管理员只能选检验所
            if (param.getInspectionId() == null) {
                param.setHospitalIdList(adminMapper.listAllHospitalId());
            }
        }
        List<DiseaseStatistics> result = Lists.newArrayList();
        try {
            DateTime montDate = DateUtil.parse(param.getMonth(), "yyyy/MM");
            DateTime beginOfMonth = DateUtil.beginOfMonth(montDate);
            DateTime endOfMonth = DateUtil.endOfMonth(montDate);

            Long getDiseaseNum50 = 0L;
            Long getDiseaseNum50_5000 = 0L;
            Long getDiseaseNum5000 = 0L;
            List<SamplingRecordResult> resultList = samplingRecordMapper.listDiseaseResultByCondition(param.getInspectionId(), param.getHospitalIdList(), beginOfMonth.toJdkDate(), endOfMonth.toJdkDate());
            if (CollectionUtils.isNotEmpty(resultList)) {
                getDiseaseNum50 = resultList.stream().filter(item->Objects.nonNull(item.getDiseaseNum())).filter(item -> item.getDiseaseNum() < 50).count();
                getDiseaseNum50_5000 = resultList.stream().filter(item->Objects.nonNull(item.getDiseaseNum())).filter(item -> item.getDiseaseNum() >= 50 && item.getDiseaseNum() <= 5000).count();
                getDiseaseNum5000 = resultList.stream().filter(item->Objects.nonNull(item.getDiseaseNum())).filter(item -> item.getDiseaseNum() > 5000).count();
            }
            DiseaseStatistics one = new DiseaseStatistics();
            one.setName("病载含量：<50");
            one.setNum(getDiseaseNum50);
            result.add(one);

            DiseaseStatistics two = new DiseaseStatistics();
            two.setName("病载含量：50-5000");
            two.setNum(getDiseaseNum50_5000);
            result.add(two);

            DiseaseStatistics three = new DiseaseStatistics();
            three.setName("病载含量：>5000");
            three.setNum(getDiseaseNum5000);
            result.add(three);
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "月份格式错误 格式：yyyy/mm");
        }
        return result;
    }

    /**
     * 检测趋势图统计信息
     *
     * @param admin
     * @param param
     * @return
     */
    public List<DrugResistanceStatistics> drugResistanceStatistics(Admin admin, StatisticsParam param) {
        AssertUtil.assertNotNull(param.getMonth(), "月份不能为空");
        if (admin.getType() == 1) {//质控中心
            if (param.getHospitalId() != null) {
                param.setHospitalIdList(Lists.newArrayList(param.getHospitalId()));
            } else {
                // 查询质控中心下的所有医院
                param.setHospitalIdList(zhiKongCenterRelationHospital(admin.getHospitalId()));
            }
        }
        if (admin.getType() == 2) {//医院
            param.setHospitalIdList(Lists.newArrayList(admin.getHospitalId()));
        }
        if (admin.getType() == 3) {//检验所
            param.setInspectionId(admin.getHospitalId());
        }
        if (admin.getType() == 0) {
            //超级管理员只能选检验所
            if (param.getInspectionId() == null) {
                param.setHospitalIdList(adminMapper.listAllHospitalId());
            }
        }
        List<DrugResistanceStatistics> result = Lists.newArrayList();
        try {
            DateTime montDate = DateUtil.parse(param.getMonth(), "yyyy/MM");
            DateTime beginOfMonth = DateUtil.beginOfMonth(montDate);
            DateTime endOfMonth = DateUtil.endOfMonth(montDate);
            AtomicReference<Integer> drugNum = new AtomicReference<>(0);
            AtomicReference<Integer> unDrugNum = new AtomicReference<>(0);

            List<SamplingRecordResult> resultList = samplingRecordMapper.listDrugResultByCondition(param.getInspectionId(), param.getHospitalIdList(), beginOfMonth.toJdkDate(), endOfMonth.toJdkDate());
            if (CollectionUtils.isNotEmpty(resultList)) {
                Map<Long, List<SamplingRecordResult>> map = resultList.stream().collect(Collectors.groupingBy(item -> item.getSamplingId()));
                map.forEach((key, list) -> {
                    long count = list.stream().filter(item -> !Objects.equals(item.getDrugResult(), "无")).count();
                    if (count == 0) {
                        unDrugNum.set(unDrugNum.get() + 1);
                    } else {
                        drugNum.set(drugNum.get() + 1);
                    }
                });
            }
            DrugResistanceStatistics one = new DrugResistanceStatistics();
            one.setName("发现耐药");
            one.setNum(drugNum.get());
            result.add(one);

            DrugResistanceStatistics two = new DrugResistanceStatistics();
            two.setName("未发现耐药");
            two.setNum(unDrugNum.get());
            result.add(two);
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "月份格式错误 格式：yyyy/mm");
        }
        return result;
    }


    /**
     * 与检验所有关的医院集合
     *
     * @return
     */
    private Set<Long> inspectionRelationHospital(Long inspectionId) {
        Set<Long> hospitalIdList = samplingBoxMapper.queryByInspectionId(inspectionId);
        return hospitalIdList;
    }
    /**
     * 与检验所有关的患者集合
     *
     * @return
     */
    private List<Long> inspectionRelationPatient(Long inspectionId) {
        Set<Long> hospitalIdsSet = samplingBoxMapper.queryByInspectionId(inspectionId);
        if (CollectionUtils.isEmpty(hospitalIdsSet)) {
            return Collections.emptyList();
        }
        List<Patient> inspectionList = patientMapper.queryByHospitalIdList(hospitalIdsSet);
        if (CollectionUtils.isEmpty(inspectionList)) {
            return Collections.emptyList();
        }

        List<Patient> distinctList = Lists.newArrayList();
        Map<String, List<Patient>> map = inspectionList.stream().collect(Collectors.groupingBy(Patient::getAntiviralCode));
        map.forEach((key, values)->{
            if (CollectionUtils.isNotEmpty(values)) {
                Patient patient = values.stream().sorted(Comparator.comparing(Patient::getCreateTime).reversed()).findFirst().orElseGet(null);
                if (patient != null) {
                    distinctList.add(patient);
                }
            }
        });

        return distinctList.stream().map(Patient::getId).collect(Collectors.toList());
    }
    /**
     * 与检验所有关的当月完成检测采样数量
     *
     * @return
     */
    private List<Long> inspectionRelationFinishInspection(Long inspectionId, Date startTime, Date endTime) {
        Set<Long> hospitalIdsSet = samplingBoxMapper.queryByInspectionId(inspectionId);
        if (CollectionUtils.isEmpty(hospitalIdsSet)) {
            return Collections.emptyList();
        }
        List<Long> finishInspectionList = samplingRecordMapper.inspectionFinishNumForHospitalIdList(hospitalIdsSet, startTime, endTime);
        return finishInspectionList;
    }

    /**
     * 与医院有关的医院集合
     *
     * @return
     */
    private Set<Long> hospitalRelationInspection(Long hospitalId) {
        Set<Long> hospitalIdList = samplingBoxMapper.queryByHospitalId(hospitalId);
        return hospitalIdList;
    }
    /**
     * 与医院有关的患者集合
     *
     * @return
     */
    private List<Long> hospitalRelationPatient(Long hospitalId) {
        List<Patient> inspectionList = patientMapper.queryByHospitalId(hospitalId);
        if (CollectionUtils.isEmpty(inspectionList)) {
            return Collections.emptyList();
        }

        List<Patient> distinctList = Lists.newArrayList();
        Map<String, List<Patient>> map = inspectionList.stream().collect(Collectors.groupingBy(Patient::getAntiviralCode));
        map.forEach((key, values)->{
            if (CollectionUtils.isNotEmpty(values)) {
                Patient patient = values.stream().sorted(Comparator.comparing(Patient::getCreateTime).reversed()).findFirst().orElseGet(null);
                if (patient != null) {
                    distinctList.add(patient);
                }
            }
        });
        return distinctList.stream().map(Patient::getId).collect(Collectors.toList());
    }
    /**
     * 与医院有关的当月完成检测采样数量
     *
     * @return
     */
    private List<Long> hospitalRelationFinishInspection(Long hospitalId, Date startTime, Date endTime) {
        Set<Long> hospitalIdsSet = Sets.newHashSet(hospitalId);
        List<Long> finishInspectionList = samplingRecordMapper.inspectionFinishNumForHospitalIdList(hospitalIdsSet, startTime, endTime);
        return finishInspectionList;
    }

    /**
     * 与质控中心有关的检验所集合
     *
     * @return
     */
    private Set<Long> qualityControlCenterRelationInspection(Long qualityControlCenterId) {
        //质控中心-则查询质控中心下所有医院
        List<Hospital> hospitals = hospitalMapper.listByParentId(qualityControlCenterId);
        if (CollectionUtils.isEmpty(hospitals)) {
            return Sets.newHashSet();
        }
        Set<Long> hospitalIdsSet = hospitals.stream().map(Hospital::getId).collect(Collectors.toSet());
        Set<Long> inspectionIdsSet = samplingBoxMapper.queryByHospitalIdList(hospitalIdsSet);
        return inspectionIdsSet;
    }
    /**
     * 与质控中心有关的患者集合
     *
     * @return
     */
    private List<Long> qualityControlCenterRelationPatient(Long qualityControlCenterId) {
        //质控中心-则查询质控中心下所有医院
        List<Hospital> hospitals = hospitalMapper.listByParentId(qualityControlCenterId);
        if (CollectionUtils.isEmpty(hospitals)) {
            return Lists.newArrayList();
        }
        Set<Long> hospitalIdsSet = hospitals.stream().map(Hospital::getId).collect(Collectors.toSet());
        List<Patient> inspectionList = patientMapper.queryByHospitalIdList(hospitalIdsSet);
        if (CollectionUtils.isEmpty(inspectionList)) {
            return Collections.emptyList();
        }

        List<Patient> distinctList = Lists.newArrayList();
        Map<String, List<Patient>> map = inspectionList.stream().collect(Collectors.groupingBy(Patient::getAntiviralCode));
        map.forEach((key, values)->{
            if (CollectionUtils.isNotEmpty(values)) {
                Patient patient = values.stream().sorted(Comparator.comparing(Patient::getCreateTime).reversed()).findFirst().orElseGet(null);
                if (patient != null) {
                    distinctList.add(patient);
                }
            }
        });

        return distinctList.stream().map(Patient::getId).collect(Collectors.toList());
    }
    /**
     * 与质控中心有关的当月完成检测采样数量
     *
     * @return
     */
    private List<Long> qualityControlCenterRelationFinishInspection(Long qualityControlCenterId, Date startTime, Date endTime) {
        //质控中心-则查询质控中心下所有医院
        List<Hospital> hospitals = hospitalMapper.listByParentId(qualityControlCenterId);
        if (CollectionUtils.isEmpty(hospitals)) {
            return Lists.newArrayList();
        }
        Set<Long> hospitalIdsSet = hospitals.stream().map(Hospital::getId).collect(Collectors.toSet());
        List<Long> finishInspectionList = samplingRecordMapper.inspectionFinishNumForHospitalIdList(hospitalIdsSet, startTime, endTime);
        return finishInspectionList;
    }

    /////
    /**
     * 质控中心采样人数
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer samplingCountForQualityControlCenterByRange(Long qualityControlCenterId, Date startTime, Date endTime) {
        //质控中心-则查询质控中心下所有医院
        List<Hospital> hospitals = hospitalMapper.listByParentId(qualityControlCenterId);
        if (CollectionUtils.isEmpty(hospitals)) {
            return 0;
        }
        Set<Long> hospitalIdsSet = hospitals.stream().map(Hospital::getId).collect(Collectors.toSet());
        return samplingRecordMapper.samplingCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }
    /**
     * 质控中心检测人数
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer inspectionCountForQualityControlCenterByRange(Long qualityControlCenterId, Date startTime, Date endTime) {
        //质控中心-则查询质控中心下所有医院
        List<Hospital> hospitals = hospitalMapper.listByParentId(qualityControlCenterId);
        if (CollectionUtils.isEmpty(hospitals)) {
            return 0;
        }
        Set<Long> hospitalIdsSet = hospitals.stream().map(Hospital::getId).collect(Collectors.toSet());
        return samplingRecordMapper.inspectionCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }
    /**
     * 质控中心检测完成数量
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer samplingFinishCountForQualityControlCenterByRange(Long qualityControlCenterId, Date startTime, Date endTime) {
        //质控中心-则查询质控中心下所有医院
        List<Hospital> hospitals = hospitalMapper.listByParentId(qualityControlCenterId);
        if (CollectionUtils.isEmpty(hospitals)) {
            return 0;
        }
        Set<Long> hospitalIdsSet = hospitals.stream().map(Hospital::getId).collect(Collectors.toSet());
        return samplingRecordMapper.samplingFinishCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }
    /**
     * 质控中心新增患者数量
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer increasePatientCountForQualityControlCenterByRange(Long qualityControlCenterId, Date startTime, Date endTime) {
        //质控中心-则查询质控中心下所有医院
        List<Hospital> hospitals = hospitalMapper.listByParentId(qualityControlCenterId);
        if (CollectionUtils.isEmpty(hospitals)) {
            return 0;
        }
        Set<Long> hospitalIdsSet = hospitals.stream().map(Hospital::getId).collect(Collectors.toSet());
        return patientMapper.increasePatientCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }

    /**
     * 医院采样人数
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer samplingCountForHospitalByRange(Long hospitalId, Date startTime, Date endTime) {
        Set<Long> hospitalIdsSet = Sets.newHashSet(hospitalId);
        return samplingRecordMapper.samplingCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }

    /**
     * 医院检测人数
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer inspectionCountForHospitalByRange(Long hospitalId, Date startTime, Date endTime) {
        Set<Long> hospitalIdsSet = Sets.newHashSet(hospitalId);
        return samplingRecordMapper.inspectionCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }

    /**
     * 医院检测完成数量
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer samplingFinishCountForHospitalByRange(Long hospitalId, Date startTime, Date endTime) {
        Set<Long> hospitalIdsSet = Sets.newHashSet(hospitalId);
        return samplingRecordMapper.samplingFinishCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }
    /**
     * 医院新增患者数量
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer increasePatientCountForHospitalByRange(Long hospitalId, Date startTime, Date endTime) {
        Set<Long> hospitalIdsSet = Sets.newHashSet(hospitalId);
        return patientMapper.increasePatientCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }

    /**
     * 检验所采样人数
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer samplingCountForInspectionByRange(Long inspectionId, Date startTime, Date endTime) {
        Set<Long> hospitalIdsSet = samplingBoxMapper.queryByInspectionId(inspectionId);
        if (CollectionUtils.isEmpty(hospitalIdsSet)) {
            return 0;
        }
        return samplingRecordMapper.samplingCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }

    /**
     * 检验所检测人数
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer inspectionCountForInspectionByRange(Long inspectionId, Date startTime, Date endTime) {
        Set<Long> hospitalIdsSet = samplingBoxMapper.queryByInspectionId(inspectionId);
        if (CollectionUtils.isEmpty(hospitalIdsSet)) {
            return 0;
        }
        return samplingRecordMapper.inspectionCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }

    /**
     * 检验所检测完成数量
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer samplingFinishCountForInspectionByRange(Long inspectionId, Date startTime, Date endTime) {
        Set<Long> hospitalIdsSet = samplingBoxMapper.queryByInspectionId(inspectionId);
        if (CollectionUtils.isEmpty(hospitalIdsSet)) {
            return 0;
        }
        return samplingRecordMapper.samplingFinishCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }
    /**
     * 检验所新增患者数量
     * @param startTime
     * @param endTime
     * @return
     */
    private Integer increasePatientCountForInspectionByRange(Long inspectionId, Date startTime, Date endTime) {
        Set<Long> hospitalIdsSet = samplingBoxMapper.queryByInspectionId(inspectionId);
        if (CollectionUtils.isEmpty(hospitalIdsSet)) {
            return 0;
        }
        return patientMapper.increasePatientCountByRangeAndHospitalIdList(hospitalIdsSet, startTime, endTime);
    }
}
